﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Security.Permissions;
using System.IO;
using System.ComponentModel;
using System.Security.Principal;

namespace BugSnapper
{
    class Program
    {
        #region Main Method
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //
            // Give our app an XP theme look.
            //
            if (!HasPriorInstance())
            {
                if (!_isAdministrator())
                {
                    MessageBox.Show("Please run the application as an Administrator.");
                    System.Environment.Exit(0);
                }
                else
                {
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.EnableVisualStyles();
                    Application.DoEvents();
                    Application.Run(new MainForm());
                }
            }
            else
            {
                MessageBox.Show("An instance of Bug Snapper is already running. Please close the previous instance and then start the application again.");
                System.Environment.Exit(0);
            }
        }


        private static bool _isAdministrator()
        {
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }


        [System.Runtime.InteropServices.DllImport("user32.dll")]
        [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        public static bool HasPriorInstance()
        {
            try
            {
                Process currentProcess = Process.GetCurrentProcess();
                string fileName = currentProcess.StartInfo.FileName;
                foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
                {
                    if (process.Id == currentProcess.Id) { continue; }
                    if (process.StartInfo.FileName != fileName)
                    {
                        continue;
                    }
                    SetForegroundWindow(process.MainWindowHandle);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Logger logger = new Logger();
                logger.ProcessError(ex);
                MessageBox.Show("Program.cs: " + ex.Message + " " + ex.StackTrace);
            }
            return false;
        }


        [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
        public static Process ElevateProcess(Process source)
        {
            //Create a new process
            Process target = new Process();
            target.StartInfo = source.StartInfo;
            target.StartInfo.FileName = source.MainModule.FileName;
            target.StartInfo.WorkingDirectory = Path.GetDirectoryName(source.MainModule.FileName);

            //Required for UAC to work
            target.StartInfo.UseShellExecute = true;
            target.StartInfo.Verb = "runas";

            try
            {
                if (!target.Start())
                    return null;
            }
            catch (Win32Exception e)
            {
                //Cancelled
                if (e.NativeErrorCode == 1223)
                    return null;
                throw;
            };
            return target;
        }

        #endregion
    }
}
